
type register = 
  | A0 | A1 | A2 | A3 (* argument *)
  | T0 | T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9 (* temporary (not preserved across call) *)
  | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 	(*saved temporary (preserved across call)*)
  | V0 | V1 (*expression evaluation and results of a function*)
  | RA (*eturn address (used by function call)*)
  | SP (* stack pointer *)
  | FP (* frame pointer *)

type address =
  | Alab of string
  | Areg of int * register

type operand =
  | Oimm of int
  | Oreg of register

type arith = Add | Sub | Mul | Div

type instruction =
  | Move of register * register
  | Li of register * int
  | La of register * string
  | Lw of register * address
  | Sw of register * address
  | Arith of arith * register * register * operand
  | Jal of string
  | Jr of register
  | Syscall
  | Label of string
  | NOP

type data = 
  | Asciiz of string * string
  | Word of string * int

type program = {
  text : instruction list;
  data : data list;
}

val print_program : Format.formatter -> program -> unit

